package com.avengers.core.kit;


import com.avengers.modules.spider.whois.bean.WhoisInfo;
import com.avengers.modules.spider.whois.querier.WhoisProp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;

import static com.avengers.core.bean.Numbers.INT_43;

/**
 * @author yu.wang
 * @since 2025/7/1 11:35
 **/
public class WhoisKit {
    private final static Logger logger = LoggerFactory.getLogger(WhoisKit.class);

    public static WhoisInfo transferInfo(String domain, String whoisSource) {
        WhoisProp whoisProp = WhoisProp.of(domain);
        if (null == whoisProp) {
            return null;
        }
        return whoisProp.transfer(domain, whoisSource);
    }

    public static WhoisInfo whoisInfo(String domain) {
        WhoisProp whoisProp = WhoisProp.of(domain);
        String sourceWhois = source(whoisProp, domain);
        if (StringKit.isBlank(sourceWhois)) {
            return null;
        }
        return whoisProp.transfer(domain, sourceWhois);
    }

    public static String source(String domain) {
        WhoisProp whoisProp = WhoisProp.of(domain);
        return source(whoisProp, domain);
    }

    private static String source(WhoisProp whoisProp, String domain) {
        if (null == whoisProp) {
            return null;
        }
        if (StringKit.isBlank(domain)) {
            return null;
        }
        if (!DomainKit.isDomain(domain)) {
            return null;
        }
        return TimeKit.logUsedTime(() -> {
            PrintWriter printWriter = null;
            InputStream inputStream = null;
            Socket socket = null;
            try {
                socket = new Socket(whoisProp.server(), INT_43);
                socket.setSoTimeout(3000);
                printWriter = new PrintWriter(socket.getOutputStream());
                printWriter.println((StringKit.hasChinese(domain) ? DomainKit.toPunyCode(domain) : domain) + "\r\n");
                printWriter.flush();

                inputStream = socket.getInputStream();

                StringBuilder out = new StringBuilder();
                byte[] b = new byte[14096];
                for (int n; (n = inputStream.read(b)) != -1; ) {
                    out.append(new String(b, 0, n));
                }
                return out.toString();
            } catch (Exception e) {
                logger.error("domain_{} query whois error: {}", domain, e.getMessage(), e);
            } finally {
                if (null != socket) {
                    try {
                        socket.shutdownOutput();
                    } catch (IOException e) {
                        logger.error("domain_{} query whois close socket error: {}", domain, e.getMessage(), e);
                    }
                    IOKit.close(logger, socket);
                }
                IOKit.close(logger, inputStream);
                IOKit.close(logger, printWriter);
            }
            return null;
        }, logger, "domain_{} query whois", domain);
    }
}
